
#include "jxos_public.h"
#include <srtnet_config.h>
#include "../communication_layer/communication_layer_frame.h"
#include "application_layer_service.h"
#include "service_define.h"

#if (SRTNET_COMM_DEVICE_TYPE == SRTNET_COMM_DEVICE_TYPE_RECEIVER)\
    ||(SRTNET_COMM_DEVICE_TYPE == SRTNET_COMM_DEVICE_TYPE_REPEATER)
typedef struct
{
	uint16_t master_addr;
	uint8_t master_service_serila_mun;
	uint8_t master_service_id;
	uint8_t slave_service_serila_mun;
} BUNDLING_STRUCT;

uint8_t (*srtnet_app_layer_binding_table_store_callback)(uint8_t* binding_table, uint8_t binding_table_len) = 0;
uint8_t (*srtnet_app_layer_binding_table_recover_callback)(uint8_t* binding_table, uint8_t binding_table_len) = 0;

#if (BUNDLING_TABLE_MAX > 0)
static BUNDLING_STRUCT binding_table[BUNDLING_TABLE_MAX];
#endif

uint8_t srtnet_app_layer_binding_table_store(void)
{
#if (BUNDLING_TABLE_MAX > 0)
	if(srtnet_app_layer_binding_table_store_callback != 0){
		return srtnet_app_layer_binding_table_store_callback((uint8_t*)binding_table, sizeof(BUNDLING_STRUCT)*BUNDLING_TABLE_MAX);
	}
#endif
	return 1;
}

void srtnet_app_layer_binding_table_clear(uint8_t slave_service_serila_mun)
{
#if (BUNDLING_TABLE_MAX > 0)
	uint8_t i;
	for(i = 0; i < BUNDLING_TABLE_MAX; i++){
		if((binding_table[i].master_addr != ADDR_BROADCAST)
		&&(binding_table[i].slave_service_serila_mun == slave_service_serila_mun)){
			binding_table[i].master_addr = ADDR_BROADCAST;
		}
	}
	srtnet_app_layer_binding_table_store();
#endif
}

uint8_t srtnet_app_layer_binding_table_recover(void)
{
#if (BUNDLING_TABLE_MAX > 0)
	if(srtnet_app_layer_binding_table_recover_callback != 0){
		return srtnet_app_layer_binding_table_recover_callback((uint8_t*)binding_table, sizeof(BUNDLING_STRUCT)*BUNDLING_TABLE_MAX);
	}
	srtnet_app_layer_binding_table_clear(0);
#endif
	return 1;
}

uint8_t srtnet_app_layer_binding_table_add(uint16_t master_addr, uint8_t master_service_serila_mun, uint8_t master_service_id,
							uint8_t slave_service_serila_mun)
{
#if (BUNDLING_TABLE_MAX > 0)
	uint8_t i;
	i = service_config_table[slave_service_serila_mun][SERVICE_CONFIG_TABLE_SERVICE_ID_OBJECT];
	if(service_config_table[slave_service_serila_mun][SERVICE_CONFIG_TABLE_SERVICE_ID_OBJECT] != master_service_id){
		return 0;
	}
	if(service_config_table[slave_service_serila_mun][SERVICE_CONFIG_TABLE_SERVICE_M_S_OBJECT] != SERVICE_SLAVE){
		return 0;
	}

	for(i = 0; i < BUNDLING_TABLE_MAX; i++){
		if(binding_table[i].master_addr == ADDR_BROADCAST){
			binding_table[i].master_addr = master_addr;
			binding_table[i].master_service_serila_mun = master_service_serila_mun;
			binding_table[i].master_service_id = master_service_id;
			binding_table[i].slave_service_serila_mun = slave_service_serila_mun;
			srtnet_app_layer_binding_table_store();
			break;
		}
	}
	if(i != BUNDLING_TABLE_MAX){
		return 1;
	}
	else{
		return 0;
	}
#endif
}

uint8_t srtnet_app_layer_binding_table_del(uint16_t master_addr, uint8_t master_service_serila_mun, uint8_t master_service_id,
							uint8_t slave_service_serila_mun)
{
#if (BUNDLING_TABLE_MAX > 0)
	uint8_t i;
	for(i = 0; i < BUNDLING_TABLE_MAX; i++){
		if((binding_table[i].master_addr == master_addr)
			&&(binding_table[i].master_service_serila_mun == master_service_serila_mun)
			&&(binding_table[i].master_service_id == master_service_id)
			&&(binding_table[i].slave_service_serila_mun == slave_service_serila_mun)){
			srtnet_app_layer_binding_table_store();
			break;
		}
	}
	if(i != BUNDLING_TABLE_MAX){
		return 1;
	}
	else{
		return 0;
	}
#endif
}

static uint8_t srtnet_app_layer_binding_table_lookup_i = 0;
void srtnet_app_layer_binding_table_lookup_reset(void)
{
	srtnet_app_layer_binding_table_lookup_i = 0;
}

uint8_t srtnet_app_layer_binding_table_lookup(uint16_t master_addr, uint8_t master_service_serila_mun, 
							uint8_t master_service_id,
							uint8_t* slave_service_serila_mun)
{
#if (BUNDLING_TABLE_MAX > 0)
	for(; srtnet_app_layer_binding_table_lookup_i < BUNDLING_TABLE_MAX; srtnet_app_layer_binding_table_lookup_i++){
		if(binding_table[srtnet_app_layer_binding_table_lookup_i].master_addr != ADDR_BROADCAST){
			if((binding_table[srtnet_app_layer_binding_table_lookup_i].master_addr == master_addr)
				&&(binding_table[srtnet_app_layer_binding_table_lookup_i].master_service_serila_mun == master_service_serila_mun)
				&&(binding_table[srtnet_app_layer_binding_table_lookup_i].master_service_id == master_service_id)){
				*slave_service_serila_mun = binding_table[srtnet_app_layer_binding_table_lookup_i].slave_service_serila_mun;
				break;
			}
		}
	}
	if(srtnet_app_layer_binding_table_lookup_i != BUNDLING_TABLE_MAX){
		srtnet_app_layer_binding_table_lookup_i++;
		return 1;
	}
	else{
		*slave_service_serila_mun = 0xff;
		srtnet_app_layer_binding_table_lookup_i = 0;
		return 0;
	}
#endif
}

uint8_t srtnet_app_layer_binding_table_is_empty(void)
{
#if (BUNDLING_TABLE_MAX > 0)
	uint8_t i;
	for(i = 0; i < BUNDLING_TABLE_MAX; i++){
		if(binding_table[i].master_addr != ADDR_BROADCAST){
			break;
		}
	}
	if(i != BUNDLING_TABLE_MAX){
		return 0;
	}
	else{
		return 1;
	}
#endif
}

void srtnet_app_layer_binding_table_print(void)
{
#if (BUNDLING_TABLE_MAX > 0)
#if (SRTNET_APP_LAYER_DEBUG_PRINT_ENABLE == 1)
	int i;
	sys_debug_print_task_user_print_str("print_binding_table:\r\n");
	for(i = 0; i < BUNDLING_TABLE_MAX; i++){
		sys_debug_print_task_user_print_str("master_addr:");
		sys_debug_print_task_user_print_hex(binding_table[i].master_addr);
		sys_debug_print_task_user_print_str(" master_service_serila_mun:");
		sys_debug_print_task_user_print_uint(binding_table[i].master_service_serila_mun);
		sys_debug_print_task_user_print_str(" master_service_id:");
		sys_debug_print_task_user_print_uint(binding_table[i].master_service_id);
		sys_debug_print_task_user_print_str(" slave_service_serila_mun:");
		sys_debug_print_task_user_print_uint(binding_table[i].slave_service_serila_mun);
		sys_debug_print_task_user_print_str("\r\n");
	}
#endif
#endif
}
#endif
